<template>
  <el-row>
    <p>{{ $t('pageKvm.status') }}:</p>
    <status-icon :status="serverStatusIcon"></status-icon>
    <p>{{ serverStatus }}</p>
  </el-row>
  <el-row>
    <div id="terminal-kvm" ref="panel1" class="relative w-[609px] h-[457px]">
      <el-button-group
        v-if="!isFullWindow"
        class="mx-auto table bg-white"
        size="large"
      >
        <el-button
          :title="$t('pageKvm.brandTitle.screenShot')"
          :icon="Camera"
          @click="jitT"
        />
        <el-button
          :class="
            immersionMode
              ? 'bg-[--el-button-hover-bg-color] text-[--el-button-hover-text-color]'
              : ''
          "
          :title="
            immersionMode
              ? $t('pageKvm.brandTitle.exitImmersionMode')
              : $t('pageKvm.brandTitle.immersionMode')
          "
          :icon="Position"
          @click="immersionClick"
        />
        <kvm-recorder :element="shotArea" />
        <screen-full :element="panel1" :isFullWindow="isFullWindow" />
        <el-button
          :title="
            powerStatus
              ? $t('pageKvm.brandTitle.shutdown')
              : $t('pageKvm.brandTitle.powerOn')
          "
          :icon="SwitchButton"
          :class="
            powerStatus
              ? 'bg-[--el-button-hover-bg-color] text-[--el-button-hover-text-color]'
              : ''
          "
          @click="togglePower"
        >
        </el-button>
      </el-button-group>
      <el-button-group
        v-else
        class="absolute bg-white left-[50%] translate-x-[-50%]"
        size="large"
      >
        <el-button
          :title="$t('pageKvm.brandTitle.screenShot')"
          :icon="Camera"
          @click="jitT"
        />
        <el-button
          :class="
            immersionMode
              ? 'bg-[--el-button-hover-bg-color] text-[--el-button-hover-text-color]'
              : ''
          "
          :title="
            immersionMode
              ? $t('pageKvm.brandTitle.exitImmersionMode')
              : $t('pageKvm.brandTitle.immersionMode')
          "
          :icon="Position"
          @click="immersionClick"
        />
        <kvm-recorder :element="shotArea" />
        <screen-full :element="panel1" :isFullWindow="isFullWindow" />
        <el-button
          :title="
            powerStatus
              ? $t('pageKvm.brandTitle.shutdown')
              : $t('pageKvm.brandTitle.powerOn')
          "
          :icon="SwitchButton"
          :class="
            powerStatus
              ? 'bg-[--el-button-hover-bg-color] text-[--el-button-hover-text-color]'
              : ''
          "
          @click="togglePower"
        >
        </el-button>
      </el-button-group>
    </div>
  </el-row>
</template>

<script setup lang="ts">
// @ts-ignore
import RFB from '@novnc/novnc/lib/rfb';
import wsUrl from '@/utilities/wsUrlTool';
import StatusIcon from '@/components/global/StatusIcon.vue';
import { Camera, Position, SwitchButton } from '@element-plus/icons-vue';
import screenFull from '@/components/global/ScreenFull.vue';
import KvmRecorder from '@/components/global/KvmRecorder.vue';
import { useI18n } from 'vue-i18n';
import { useAuthenticationStore } from '@/store/Authentication/Authentication';
import { useControlStore } from '@/store/Settings/ControlStore';
import { useGlobalStore } from '@/store/global';
import html2canvas from 'html2canvas';

onMounted(() => {
  openTerminal();
});

onBeforeUnmount(() => {
  closeTerminal();
});

const i18n = useI18n();
const authenticationStore = useAuthenticationStore();
const globalStore = useGlobalStore();
const controlStore = useControlStore();

const Connecting = 0;
const Connected = 1;
const Disconnected = 2;

const panel1 = ref();

const rfb = ref();
const isConnected = ref(false);
const status = ref(Connecting);
const shotArea = ref();
const loadFinished = ref(false);
const isFullWindow = ref(false);

provide('setIsFullWindow', (status: boolean) => {
  isFullWindow.value = status;
});

const serverStatusIcon = computed(() => {
  if (status.value === Connected) {
    return 'success';
  } else if (status.value === Disconnected) {
    return 'danger';
  }
  return 'secondary';
});
const serverStatus = computed(() => {
  if (status.value === Connected) {
    return i18n.t('pageKvm.connected');
  } else if (status.value === Disconnected) {
    return i18n.t('pageKvm.disconnected');
  }
  return i18n.t('pageKvm.connecting');
});

const closeTerminal = () => {
  rfb.value.disconnect();
  rfb.value = null;
};

const openTerminal = () => {
  const token = authenticationStore.token;
  rfb.value = new RFB(
    panel1.value,
    wsUrl(`wss://${window.location.host}/kvm/0`),
    {
      wsProtocols: [token],
    },
  );

  rfb.value.scaleViewport = true;
  rfb.value.clipViewport = true;

  rfb.value.addEventListener('connect', () => {
    isConnected.value = true;
    status.value = Connected;
    loadFinished.value = true;
    shotArea.value = document.querySelector('#terminal-kvm > div > canvas');
  });

  rfb.value.addEventListener('disconnect', () => {
    isConnected.value = false;
    status.value = Disconnected;
  });
};

const powerOn = () => {
  ElMessageBox.confirm(
    i18n.t('pageServerPowerOperations.modal.confirmPowerOnMessage'),
    i18n.t('pageServerPowerOperations.modal.confirmPowerOnTitle'),
    {
      confirmButtonText: i18n.t('global.action.confirm'),
      cancelButtonText: i18n.t('global.action.cancel'),
    },
  ).then((confirmed: any) => {
    if (confirmed) controlStore.serverPowerOn();
  });
};

const shutdownServer = () => {
  ElMessageBox.confirm(
    i18n.t('pageServerPowerOperations.modal.confirmShutdownTitle'),
    i18n.t('pageServerPowerOperations.modal.confirmShutdownMessage'),
    {
      confirmButtonText: i18n.t('global.action.confirm'),
      cancelButtonText: i18n.t('global.action.cancel'),
    },
  ).then((confirmed: any) => {
    if (confirmed) controlStore.serverHardPowerOff();
  });
};

const powerStatus = computed(() => {
  let op = globalStore.serverStatus;
  switch (op) {
    case 'off':
      return false;
    case 'unreachable':
      return false;
    default:
      return true;
  }
});

const togglePower = () => {
  if (powerStatus.value) {
    shutdownServer();
  } else {
    powerOn();
  }
};

const immersionMode = ref(false);
const immersionClick = () => {
  if (!panel1.value) {
    ElNotification({
      type: 'error',
      message: i18n.t('global.toast.noArea'),
    });
    return;
  }
  immersionMode.value = !immersionMode.value;
  console.dir(panel1.value.children[1]);
  if (immersionMode.value) {
    panel1.value.children[1].children[0].classList.add('cursor-none');
  } else {
    panel1.value.children[1].children[0].classList.remove('cursor-none');
  }
};

const jitT = async () => {
  let imgUrl: string = await new Promise((resolve) => {
    setTimeout(() => {
      html2canvas(panel1.value.children[1].children[0], {
        useCORS: true,
        scale: window.devicePixelRatio < 3 ? window.devicePixelRatio : 2,
        allowTaint: true,
      })
        .then((canvas) => {
          const imgData = canvas.toDataURL('image/png');
          resolve(imgData);
        })
        .catch(() => {
          ElNotification({
            type: 'error',
            message: i18n.t('global.toast.screenShotFailed'),
          });
        });
    }, 300);
  });
  // Simulate the action that click a tag for downloading.
  var link = document.createElement('a');
  link.href = imgUrl;
  link.download = await globalStore.getNowDateTime();
  link.click();
  link.remove();
};

watch(isFullWindow, (newvalue) => {
  if (newvalue) {
    if ((navigator as any).keyboard && (navigator as any).keyboard.lock) {
      (navigator as any).keyboard.lock();
    } else {
      console.log('Your browser Not support!!!');
    }
  }
});
</script>
